package main

import (
	"fmt"
	"time"
)

func worker(id int, c chan int) {
	//for {
	//	// 接收方接收到发送方的close进行中断
	//	n, ok := <- c
	//	if !ok {
	//		break
	//	}
	//	//n := <-c  // channel 输出给 n
	//	fmt.Printf("Worker %d received %d\n", id, n)  // c% 是字符类型
	//}
	for n := range c {
		fmt.Printf("Worker %d received %d\n", id, n)
	}
}

func createWorker(id int) chan<- int { // chan <- int channel只能收数据； <- chan int channel只能发数据
	// chan 作为返回值
	// 函数是创建worker, 创建 go func
	c := make(chan int)
	go worker(id, c)
	return c
}

func chanDemo() {
	//var c chan int  // var 定义了c是channel int类型 c == nil 无法运用
	var channels [10]chan<- int // channel只能收数据

	for i := 0; i < 10; i++ {
		channels[i] = createWorker(i)
	}

	for i := 0; i < 10; i++ {
		channels[i] <- 'a' + i
	}

	for i := 0; i < 10; i++ {
		channels[i] <- 'A' + i
	}
	time.Sleep(time.Millisecond) // 估算任务时间来阻塞主程，不合理，理应有明确的的通知
}

func bufferedChannel() {
	c := make(chan int, 3) // 建立缓冲区有利于提升性能
	go worker(0, c)        // 没有接收者时，传入三个数据也不会出现死锁
	c <- 'a'
	c <- 'b'
	c <- 'c'
	c <- 'd'
	time.Sleep(time.Millisecond)
}

func channelClose() {
	// 数据有明确的结尾，需要关闭channel，数据发送方来发送给数据接收方的
	c := make(chan int, 3) // 建立缓冲区有利于提升性能
	go worker(0, c)
	c <- 'a'
	c <- 'b'
	c <- 'c'
	c <- 'd'
	//close(c) // 发完a,b,c,d后接收方仍然会收1ms的空串或者0
	time.Sleep(time.Millisecond)
}

func main() {
	//fmt.Println("Channel as first-class citizen")
	chanDemo()
	//fmt.Println("Buffered channel")
	//bufferedChannel()
	//fmt.Println("Channel close and range")
	//channelClose()
}
